<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>属性描述对象的获取</title>
</head>
<body>
    <script>
        // Object.is() ES6 引入的同值相等算法 类似于'==='
        // 解决 +0 -0 NaN的问题
        console.log(Object.is(+0,-0)) // false
        console.log(Object.is(NaN,NaN)) // true

        // Object.assign() 用于对象合并 将源对象所有可枚举属性复制到目标对象
        const target = {
            a:1,
            b:2
        }
        const obj1 = {
            b:2,
            c:2
        }
        const obj2 = {
            c:3
        }
        Object.assign(target,obj1,obj2)
        console.log(target)

        // 核心注意点
        // 1.浅拷贝 如果拷贝对象的属性是个对象 则该方法执行的是浅拷贝
        // 2.同名属性的替换 一旦遇到同名属性 则替换原有的属性
        // 3.数组处理 会视为对象处理 源数组会覆盖目标数组
        // 4.取值函数的处理 只会复制函数执行取值之后的结果

        // 常见使用领域
        // 1.为对象添加属性
        let o = {
            constructor(x,y){
                Object.assign(this,{x,y})
            }
        }
        o.constructor(1,3)

        // 2.为对象添加方法

        // Object.assign(someClass.prototype,{
        //     someMethod(method){
        //         // ...
        //     },
        //     anotherMethod(method){
        //         // ...
        //     }
        // })

        // 3.克隆对象 浅拷贝 不能克隆继承的值
        // 要想保持继承连 则
        function clone(origin) {
            let originPrototype = Object.getPrototypeOf(origin)
            return Object.assign(Object.create(originPrototype),origin)
        }

        // 4.合并多个对象
        const merge = (target,...source) => Object.assign(target,...source)

        // 5.为属性指定默认值
        const DEFAULTS = {
            logLevel: 0,
            outputFormat: 'html5'
        }
        function processOptions(options)  {
            options = Object.assign({},DEFAULTS,options)
            console.log(options)
            // ...
        }

        // 属性描述对象的获取
        // ES2017 引入的Object.getOwnPropertyDescriptors() 方法 返回指定对象所有自身属性
        // 引入目的 解决assign无法正确拷贝get 和 set属性的问题

        const source = {
            set foo(value){
                console.log(value)
            }
        }

        const target1 = {}
        Object.assign(target1,source)
        console.log(Object.getOwnPropertyDescriptors(target1,'foo'))

        // 原型的设置与获取
        Object.setPrototypeOf({},null) // 设置
        Object.getPrototypeOf({}) // 获取

        // 对象的遍历
        let obj = {
            foo: 'bar',
            baz: 42
        }
        console.log(Object.keys(obj)) // 返回一个数组 属性名遍历
        console.log(Object.values(obj)) // 返回一个数组 属性值遍历
        console.log(Object.entries(obj)) // 返回一个二维数组 [[属性名，属性值]] 忽略Symbol
        console.log(Object.fromEntries([
            ['0',1],
            ['1',2]
        ])) // entries 的逆向操作 转化成一个对象



    </script>
</body>
</html>